﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Tracy.DataModel;
using System.Xml;
using System.Xml.XPath;

namespace Tracy.DataAccess
{
    public class MediaFileProvider : TracyXmlDataProvider<MediaFile>
    {
        public override string FileName
        {
            get { return "MediaFiles.xml"; }
        }

        public override string RootNodeName
        {
            get { return "media-files"; }
        }

        public override string DataItemPath
        {
            get { return "media-files/media-file"; }
        }

        public List<MediaFile> GetItemsByResource(Resource res)
        {
            List<MediaFile> rtn = new List<MediaFile>();
            foreach (XmlNode node in root.SelectNodes(String.Format("media-file[resource-id='{0}']", res.ID)))
            {
                MediaFile file = new MediaFile(node);
                if (file.Resource == null) file.Resource = res;
                rtn.Add(file);
            }
            return rtn;
        }

        public List<MediaFile> GetItemsByEntry(Entry entry)
        {
            List<MediaFile> rtn = new List<MediaFile>();
            foreach (Resource res in TracyFacade.Instance.ResourceProvider.GetItemsByEntry(entry))
            {
                foreach (XmlNode node in root.SelectNodes(String.Format("media-file[resource-id='{0}']", res.ID)))
                {
                    MediaFile file = new MediaFile(node);
                    if (file.Resource == null) file.Resource = res;
                    rtn.Add(file);
                }
            }
            
            return rtn;
        }

        public List<MediaFile> GetIncompleteFiles()
        {
            List<MediaFile> rtn = new List<MediaFile>();

            foreach (XmlNode node in root.SelectNodes("media-file[@status='New' or @status='In Progress'  or @status='Copying' or @status='Moving' or @status='Missing']"))
            {
                MediaFile file = new MediaFile(node);
                rtn.Add(file);
            }

            return rtn;
        }

        private Dictionary<string, int> _unwatchedCountCache = new Dictionary<string, int>();
        protected override void DoAddItem(MediaFile rawItem)
        {
            if (rawItem.Status == "Ready" && rawItem.Visible == "true")
            {
                lock (_unwatchedCountCache)
                {
                    _unwatchedCountCache[rawItem.Resource.Entry.ID] = -1; //mark dirty
                }
            }
            base.DoAddItem(rawItem);
        }

        protected override void DoUpdateItem(MediaFile oldItem, MediaFile newItem)
        {
            //MediaFile oldFile = GetItemByID(item.ID);
            if (newItem.Visible == "true" && (oldItem == null || oldItem.Status != newItem.Status))
            {
                lock (_unwatchedCountCache)
                {
                    _unwatchedCountCache[newItem.Resource.Entry.ID] = -1; //mark dirty
                }
            }
            base.DoUpdateItem(oldItem, newItem);
        }

        protected override void DoRemoveItem(MediaFile file)
        {
            if (file.Visible == "true")
            {
                lock (_unwatchedCountCache)
                {
                    _unwatchedCountCache[file.Resource.Entry.ID] = -1; //mark dirty
                }
            }
            base.DoRemoveItem(file);
        }

        public int GetUnwatchedCount(Entry entry)
        {
            if (_unwatchedCountCache.ContainsKey(entry.ID) && _unwatchedCountCache[entry.ID] >= 0)
            {
                return _unwatchedCountCache[entry.ID];
            }
            int rtn = 0;
            XPathNavigator nav = root.CreateNavigator();
            foreach (Resource res in TracyFacade.Instance.ResourceProvider.GetItemsByEntry(entry))
            {
                rtn += Convert.ToInt32(nav.Evaluate(String.Format("count(media-file[resource-id='{0}' and @status='Ready' and @visible='true'])", res.ID)));
            }

            lock (_unwatchedCountCache)
            {
                _unwatchedCountCache[entry.ID] = rtn; //mark dirty
            }

            return rtn;
        }

        
    }
}
